动态是指根据参数传递查询语句,但这里存在风险。
@Select("${nativeSql}")List<Map<String, String>> queryAllSubscribers(@Param("nativeSql") String nativeSql);
通过游标cursor可以高效读取百万数据。但需要开启事务,或者自己获取session来进行操作。
businessMapper
@Select("select * from subscriber")@Options(resultSetType = ResultSetType.FORWARD_ONLY, fetchSize = 1000)Cursor<Map<String, String>> queryAllSubscribers();
Service
@Transactional(readOnly = true)public exportData(){try (Cursor<Map<String, String>> cursor = businessMapper.queryAllSubscribers()) {cursor.forEach(entity -> {//TODO 处理读取的数据});}catch (Exception e) {//....}}
还有另一种方案,使用ResultHandler,这个也是游标,未测试,仅记录一下。
public interface OrderMapper extends BaseMapper<Order> {@Select("select * from tap_order ${ew.customSqlSegment}")@Options(resultSetType = ResultSetType.FORWARD_ONLY, fetchSize = Integer.MIN_VALUE)@ResultType(Order.class)void export(@Param("ew") Wrapper wrapper, ResultHandler<Order> handler);}
fetchSize = Integer.MIN_VALUE 代表每次只取一条数据